Distributed systems allow multiple clients in a network to access a pool of shared resources. For example, a distributed storage system allows a cluster of host computers to aggregate local disks (e.g., solid-state drive (SSD), peripheral component interconnect-based (PCI) flash storage, or serial AT attachment (SATA) or serial access storage (SAS) magnetic disks) located in or attached to each host computer to create a single and shared pool of storage. This pool of storage (sometimes referred to as a “datastore” or “store”) is accessible by all host computers in the cluster and may be presented as a single namespace of storage entities (such as a hierarchical file system namespace in the case of files, a flat namespace of unique identifiers in the case of objects, etc.). Storage clients in turn, such as virtual machines (VMs) spawned on the host computers, may use the datastore, for example, to store virtual disks that are accessed by the virtual machines during their operation.
This approach provides enterprises with cost-effective performance. For instance, distributed storage using pooled local disks is inexpensive, highly scalable, and relatively simple to manage. Because such distributed storage can use commodity disks in the cluster, enterprises do not need to invest in additional storage infrastructure. However, one issue with such a distributed system is how to prevent multiple users, clients, or VMs from attempting to make simultaneous, potentially conflicting, input/output (I/O) requests to the datastore. Existing systems utilize a heavy-duty lock system, only permitting access to the datastore to the user, client, VM, etc. which has the appropriate authority (e.g., the disk is unlocked for editing for that user, while locked to other users). Existing lock systems are, in some examples, too cumbersome and expensive, as they require more time and processing resources due to communication back and forth between the datastore and the users and extra I/O incurred during the lock/unlock operation.